package com.tanhua.manage.service;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.tanhua.domain.db.Freeze;
import com.tanhua.domain.db.Unfreeze;
import com.tanhua.domain.db.UserInfo;
import com.tanhua.domain.mongo.Comment;
import com.tanhua.domain.mongo.Publish;
import com.tanhua.domain.mongo.Video;
import com.tanhua.domain.vo.CommentVo;
import com.tanhua.domain.vo.MovementsVo;
import com.tanhua.domain.vo.PageResult;
import com.tanhua.domain.vo.VideoVo;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.dubbo.api.mongo.CommentApi;
import com.tanhua.dubbo.api.mongo.PublishApi;
import com.tanhua.dubbo.api.mongo.VideoApi;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.messaging.MessagingException;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.text.SimpleDateFormat;
import java.time.Duration;
import java.util.*;

@Service
public class UserService {
    @Reference
    private UserInfoApi userInfoApi;
    @Reference
    private VideoApi videoApi;
    @Reference
    private PublishApi publishApi;
    @Reference
    private CommentApi commentApi;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;


    /**
     * 接口名称：用户数据翻页
     */
    public ResponseEntity<Object> findByPage(Integer page, Integer pagesize) {
        // 调用Api，分页查询用户
        IPage<UserInfo> iPage = userInfoApi.findByPage(page,pagesize);
        // 封装分页对象
        PageResult pageResult = new PageResult(
                page,pagesize, (int) iPage.getTotal(),iPage.getRecords());
        // 返回
        return ResponseEntity.ok(pageResult);
    }

    /**
     * 接口名称：用户基本资料
     */
    public ResponseEntity<Object> findUserInfoById(Long userId) {
        UserInfo userInfo = userInfoApi.findById(userId);
        return ResponseEntity.ok(userInfo);
    }

    /**
     * 接口名称：视频记录翻页
     */
    public ResponseEntity<Object> findVideosList(
            Integer page, Integer pagesize, Long uid) {
        // 调用Api服务，分页查询用户的视频列表
        PageResult pageResult = videoApi.queryVideoList(page, pagesize, uid);
        //2. 获取分页数据
        List<Video> videoList = (List<Video>) pageResult.getItems();
        //3. 创建返回的vo集合
        List<VideoVo> voList = new ArrayList<>();
        //4. 封装vo集合
        if (videoList != null) {
            for (Video video : videoList) {
                //3.1 创建vo对象，封装前端返回的数据
                VideoVo vo = new VideoVo();
                BeanUtils.copyProperties(video,vo);
                //3.2 根据用户id查询用户并封装
                UserInfo userInfo = userInfoApi.findById(video.getUserId());
                if (userInfo!= null) {
                    BeanUtils.copyProperties(userInfo,vo);
                }
                //3.3 设置小视频封面
                vo.setCover(video.getPicUrl());
                //3.4 设置id、签名
                vo.setId(video.getId().toString());
                vo.setSignature(video.getText());
                vo.setHasLiked(0);
                vo.setHasFocus(0);
                //3.5 vo添加到集合
                voList.add(vo);
            }
        }

        //5. 设置到分页对象中
        pageResult.setItems(voList);
        return ResponseEntity.ok(pageResult);
    }

    /**
     * 接口名称：动态分页
     */
    public ResponseEntity<Object> findMovementsList(
            Integer page, Integer pagesize, Long uid, String state) {
        PageResult pageResult = publishApi.findPublishList(page,pagesize,uid,state);
        this.setMovementsVo(pageResult);
        return ResponseEntity.ok(pageResult);
    }

    // 抽取的公用方法：把pageResult中的动态集合，转换为movomentsVo集合
    public void setMovementsVo(PageResult pageResult) {
        //3. 获取返回的动态集合
        List<Publish> publishList = (List<Publish>) pageResult.getItems();
        //4. 定义接口返回的vo集合
        List<MovementsVo> voList = new ArrayList<>();
        //4.1 封装数据
        if (!CollectionUtils.isEmpty(publishList)) {
            for (Publish publish : publishList) {
                // 4.2创建对象
                MovementsVo vo = new MovementsVo();
                // 数据封装 publish--->vo
                this.convertPublishToMovementsVo(publish,vo);
                // 添加到结合
                voList.add(vo);
            }
        }
        //5. 返回
        pageResult.setItems(voList);
    }

    // 把publish--->movementsVo对象
    public void convertPublishToMovementsVo(Publish publish,MovementsVo vo){
        // 4.3 封装对象
        // 根据用户id查询
        UserInfo userInfo = userInfoApi.findById(publish.getUserId());
        if (userInfo != null) {
            BeanUtils.copyProperties(userInfo,vo);
            if (userInfo.getTags() != null) {
                vo.setTags(userInfo.getTags().split(","));
            }
        }
        // 对象拷贝：publish--->vo
        BeanUtils.copyProperties(publish,vo);
        // 设置动态id
        vo.setId(publish.getId().toString());
        // 设置动态图片： 从publish中获取的是List集合，需要转换为vo需要的数组
        vo.setImageContent(publish.getMedias().toArray(new String[]{}));
        // 设置动态发布的时间：如 1小时之前
        vo.setCreateDate(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(publish.getCreated())));
        vo.setDistance("50米");
        vo.setHasLiked(0);
        vo.setHasLoved(0);
    }

    /**
     * 接口名称：动态详情
     */
    public ResponseEntity<Object> findMovementsById(String publishId) {
        // 调用Api服务，根据动态id查询
        Publish publish = publishApi.findById(publishId);
        // 封装返回结果
        MovementsVo vo = new MovementsVo();
        this.convertPublishToMovementsVo(publish,vo);
        return ResponseEntity.ok(vo);
    }

    /**
     * 接口名称：评论列表翻页
     */
    public ResponseEntity<Object> commentsList(
            Integer page, Integer pagesize, String publishId) {
        // 根据动态id,查询评论列表
        PageResult pageResult =
                commentApi.findByPublishId(publishId, page, pagesize);
        //2. 获取分页数据
        List<Comment> list = (List<Comment>) pageResult.getItems();
        //3. 创建并封装vo集合
        List<CommentVo> voList = new ArrayList<>();
        //4. 封装voList
        if (!CollectionUtils.isEmpty(list)) {
            for (Comment comment : list) {
                // 根据用户id查询
                UserInfo userInfo = userInfoApi.findById(comment.getUserId());
                // 创建vo对象并封装
                CommentVo vo = new CommentVo();
                vo.setId(comment.getId().toString());
                vo.setAvatar(userInfo.getAvatar());
                vo.setNickname(userInfo.getNickname());
                vo.setContent(comment.getContent());
                vo.setCreateDate(new SimpleDateFormat("yyyy年MM月dd日 HH:mm")
                        .format(new Date(comment.getCreated())));
                vo.setLikeCount(0);
                vo.setHasLiked(0);
                // 添加到集合
                voList.add(vo);
            }
        }
        //5. 设置到分页对象、返回
        pageResult.setItems(voList);
        return ResponseEntity.ok(pageResult);
    }

    /**
     * 接口名称：动态审核通过
     * @param ids
     * @return
     */
    public ResponseEntity<Object> movementsPass(String[] ids) {
        String result=publishApi.movementsPass(ids);

        return ResponseEntity.ok(result);
    }

    /**
     * 接口名称：动态审核拒绝
     * @param ids
     * @return
     */
    public ResponseEntity<Object> movementsReject(String[] ids) {
        String result=publishApi.movementsReject(ids);
        return ResponseEntity.ok(result);
    }


    /**
     * 定时发送MQ消息
     * @param userId
     * @param freezingTime
     * @param freezingRange
     * @param reasonsForFreezing
     * @param frozenRemarks
     */
    public void timing(Integer userId, Integer freezingTime, Integer freezingRange, String reasonsForFreezing, String frozenRemarks){

        Timer timer = new Timer();

        TimerTask timerTask = new TimerTask() {
            @Override
            public void run() {
                String key="freezingTime_"+userId;
                Map<String, String> map=new HashMap<>();
                map.put("userId",userId.toString());
                map.put("freezingTime",freezingTime.toString());
                map.put("freezingRange",freezingRange.toString());
                map.put("reasonsForFreezing",reasonsForFreezing);
                map.put("frozenRemarks",frozenRemarks);
                //判断redis冻结时间是否过期
                if (!redisTemplate.hasKey(key)) {
                    try {
                        //过期发消息到mq
                        rocketMQTemplate.convertAndSend("freeze", JSON.toJSONString(map));
                    } catch (MessagingException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        //定时任务，每过多久执行一次任务
        timer.schedule(timerTask,1000*60*3);//3分钟
    }

    /**
     * 接口名称：用户冻结
     * @param userId
     * @param freezingTime
     * @param freezingRange
     * @param reasonsForFreezing
     * @param frozenRemarks
     * @return
     */

    public ResponseEntity<Object> freeze(Integer userId, Integer freezingTime, Integer freezingRange, String reasonsForFreezing, String frozenRemarks) {

        UserInfo userInfo = userInfoApi.findById(Long.valueOf(userId));
        String userStatus = userInfo.getUserStatus();
        //String key="freezingTime_"+userId+freezingRange;
        String key="freezingTime_"+userId;
        String value=reasonsForFreezing+"=>备注:"+frozenRemarks;
        Map<String, String> map=new HashMap<>();
        map.put("userId",userId.toString());
        map.put("freezingTime",freezingTime.toString());
        map.put("freezingRange",freezingRange.toString());
        map.put("reasonsForFreezing",reasonsForFreezing);
        map.put("frozenRemarks",frozenRemarks);
        //判断
        if(freezingRange ==1) {//冻结范围
            if (freezingTime == 1) {//冻结时间
                //修改用户状态
                userInfo.setUserStatus("2");
                userInfoApi.update(userInfo);
                //冻结时间存储到redis
                redisTemplate.opsForValue().set(key + "_登录冻结", value, Duration.ofMinutes(3));
                //监听冻结时间是否过期//自动解冻
                this.timing(userId, freezingTime, freezingRange, reasonsForFreezing, frozenRemarks);
            } else if (freezingTime == 2) {//冻结时间
                userInfo.setUserStatus("2");
                userInfoApi.update(userInfo);
                redisTemplate.opsForValue().set(key + "_登录冻结", value, Duration.ofDays(7));
                this.timing(userId, freezingTime, freezingRange, reasonsForFreezing, frozenRemarks);
            } else if (freezingTime == 3) {//冻结时间
                userInfo.setUserStatus("2");
                userInfoApi.update(userInfo);
                redisTemplate.opsForValue().set(key + "_登录冻结", value, Duration.ofDays(99999));
                this.timing(userId, freezingTime, freezingRange, reasonsForFreezing, frozenRemarks);
            }
        } else if (freezingRange == 2) {//冻结范围
            userInfo.setUserStatus("2");
            userInfoApi.update(userInfo);
            if (freezingTime == 1) {//冻结时间
                redisTemplate.opsForValue().set(key + "_评论冻结", value, Duration.ofMinutes(1));
                this.timing(userId, freezingTime, freezingRange, reasonsForFreezing, frozenRemarks);
            } else if (freezingTime == 2) {//冻结时间
                userInfo.setUserStatus("2");
                userInfoApi.update(userInfo);
                redisTemplate.opsForValue().set(key + "_评论冻结", value, Duration.ofDays(7));
                this.timing(userId, freezingTime, freezingRange, reasonsForFreezing, frozenRemarks);
            } else if (freezingTime == 3) {//冻结时间
                userInfo.setUserStatus("2");
                userInfoApi.update(userInfo);
                redisTemplate.opsForValue().set(key + "_评论冻结", value, Duration.ofDays(99999));
                this.timing(userId, freezingTime, freezingRange, reasonsForFreezing, frozenRemarks);
            }
        } else if (freezingRange == 3) {//冻结范围
            userInfo.setUserStatus("2");
            userInfoApi.update(userInfo);
            if (freezingTime == 1) {//冻结时间
                redisTemplate.opsForValue().set(key + "_动态冻结", value, Duration.ofMinutes(1));
                this.timing(userId, freezingTime, freezingRange, reasonsForFreezing, frozenRemarks);
            } else if (freezingTime == 2) {//冻结时间
                userInfo.setUserStatus("2");
                userInfoApi.update(userInfo);
                redisTemplate.opsForValue().set(key + "_动态冻结", value, Duration.ofDays(7));
                this.timing(userId, freezingTime, freezingRange, reasonsForFreezing, frozenRemarks);
            } else if (freezingTime == 3) {//冻结时间
                userInfo.setUserStatus("2");
                userInfoApi.update(userInfo);
                redisTemplate.opsForValue().set(key + "_动态冻结", value, Duration.ofDays(99999));
                this.timing(userId, freezingTime, freezingRange, reasonsForFreezing, frozenRemarks);
            }
        }
        return ResponseEntity.ok("true");
    }

    /**
     * 接口名称:用户解冻
     * @param userId
     * @param reason
     * @return
     */
    public ResponseEntity<Object> unfreeze(Long userId, String reason) {
        Unfreeze unfreeze = new Unfreeze();
        //设置解冻用户id
        unfreeze.setUserId(userId);
        //设置解冻原因
        unfreeze.setReasonsForThawing(reason);
        //获取冻结的redis
        String key="freezingTime_"+userId;
        //修改用户状态
        UserInfo userInfo = userInfoApi.findById(userId);
        userInfo.setUserStatus("1");//解冻
        userInfoApi.update(userInfo);
        //删除redis冻结用户
        if(redisTemplate.hasKey(key)){
            redisTemplate.delete(key);
        }
        //返回
        return ResponseEntity.ok("true");
    }
}
